package com.css.fxfzfxqh.modules.buildingKilometerGrid.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.poi.excel.ExcelWriter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzfxqh.base.attachment.entity.AttachmentInfoEntity;
import com.css.fxfzfxqh.base.attachment.service.AttachmentInfoService;
import com.css.fxfzfxqh.base.dict.repository.entity.DictItemEntity;
import com.css.fxfzfxqh.base.dict.service.DictItemService;
import com.css.fxfzfxqh.base.dict.viewobjects.DictEntityVo;
import com.css.fxfzfxqh.common.rest.JcsjRestManager;
import com.css.fxfzfxqh.common.utils.ZipUtils;
import com.css.fxfzfxqh.constants.FxfzConstants;
import com.css.fxfzfxqh.constants.YNEnum;
import com.css.fxfzfxqh.exceptions.ShpFieldException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.StrategyFactoryException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.PageResult;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.entity.FxqhBuildingGridDataVersion;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.param.*;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.vo.*;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.repository.FxqhBuildingGridFieldDescRepository;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.repository.FxqhBuildingGridVersionRepository;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.strategy.ShpService;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.strategy.StrategyFactory;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.threadpool.BizThreadPoolManage;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.utils.ExcelUtils;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.utils.ExportZipUtils;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.vo.Grid13VO;
import com.css.fxfzfxqh.modules.util.hypergraph.service.HypergraphService;
import com.css.fxfzfxqh.util.*;
import com.css.fxfzfxqh.web.PlatformSessionContext;
import com.css.fxfzfxqh.zcpt.sys.entity.SUser;
import com.css.fxfzfxqh.zcpt.sys.service.SUserService;
import com.css.fxfzfxqh.zcpt.sys.service.SysAreaService;
import com.css.fxfzfxqh.zcpt.sys.service.impl.SysAreaCacheService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ResourceUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.*;
import java.net.URLEncoder;
import java.nio.BufferUnderflowException;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 建筑物公里格网数据版本管理service
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class FxqhBuildingGridDataVersionService {
    @Autowired
    private FxqhBuildingGridVersionRepository fxqhBuildingGridVersionRepository; // 数据版本管理
    @Autowired
    private AttachmentInfoService attachmentInfoService; // 附件
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DictItemService dictItemService;
    @Autowired
    private SysAreaService sysAreaService;
    @Autowired
    private SysAreaCacheService sysAreaCacheService;
    @Autowired
    private SUserService sUserService;

    @Value("${image.localDir}")
    private String localDir;

    // 版本号前缀
    public static final String DATA_VERSION_CODE_PREFIX = "JZWWG";
    // 版本实体详情缓存
    public static final String FXQH_BUILDING_GRID_VERSION_DETAILS_CACHE = "fxqh:building_grid:details:version:";
    // 数据版本号流水号redis key
    public static final String DATA_VERSION_CODE_SERIAL_NUMBER_KEY = "fxqh:building_grid:data_version_code:serial_number";
    // 建筑物公里网格字典code
    public static final String DICT_CODE = "jzwglgwlx";
    // 用户信息缓存
    String SYS_USER_INFO_KEY = "fxqh:sys:details:user";

    @Autowired
    private FxqhBuildingGridFieldDescRepository fxqhBuildingGridFieldDescRepository;
    @Autowired
    private StrategyFactory strategyFactory;
    @Autowired
    FxqhBuildingGridService fxqhBuildingGridService;
    @Autowired
    private JcsjRestManager jcsjRestManager;

    @Autowired
    private FxqhBuildingGridUrbanOtherService fxqhBuildingGridUrbanOtherService;
    @Autowired
    private FxqhBuildingGridUrbanSteelService fxqhBuildingGridUrbanSteelService;
    @Autowired
    private FxqhBuildingGridUrbanSteelConcreteService fxqhBuildingGridUrbanSteelConcreteService;
    @Autowired
    private FxqhBuildingGridUrbanWoodService fxqhBuildingGridUrbanWoodService;
    @Autowired
    private FxqhBuildingGridUrbanMasonryService fxqhBuildingGridUrbanMasonryService;
    @Autowired
    private FxqhBuildingGridRuralWoodBambooService fxqhBuildingGridRuralWoodBambooService;
    @Autowired
    private FxqhBuildingGridRuralSteelService fxqhBuildingGridRuralSteelService;
    @Autowired
    private FxqhBuildingGridRuralSteelConcreteService fxqhBuildingGridRuralSteelConcreteService;
    @Autowired
    private FxqhBuildingGridRuralOtherService fxqhBuildingGridRuralOtherService;
    @Autowired
    private FxqhBuildingGridRuralMixedService fxqhBuildingGridRuralMixedService;
    @Autowired
    private FxqhBuildingGridRuralMasonryService fxqhBuildingGridRuralMasonryService;
    @Autowired
    private FxqhBuildingGridRuralCivilService fxqhBuildingGridRuralCivilService;
    @Autowired
    private FxqhBuildingGridRuralBottomFrameService fxqhBuildingGridRuralBottomFrameService;
    @Autowired
    HypergraphService hypergraphService;

    private static final String GRID_TYPE_FILE_FORMAT[] = {
            "城镇砌体结构房屋格网",
            "城镇钢混结构房屋格网",
            "城镇钢结构房屋格网",
            "城镇木结构房屋格网",
            "城镇其他结构房屋格网",
            "农村砌体结构房屋格网",
            "农村土木石木结构房屋格网",
            "农村底部框架结构房屋格网",
            "农村木竹结构房屋格网",
            "农村混杂结构房屋格网",
            "农村钢混结构房屋格网",
            "农村钢结构房屋格网",
            "农村其他结构房屋格网"
    };
    public static final String[] tables = {
            "fxqh_building_grid_rural_bottom_frame",
            "fxqh_building_grid_rural_civil",
            "fxqh_building_grid_rural_masonry",
            "fxqh_building_grid_rural_mixed",
            "fxqh_building_grid_rural_other",
            "fxqh_building_grid_rural_steel",
            "fxqh_building_grid_rural_steel_concrete",
            "fxqh_building_grid_rural_wood_bamboo",
            "fxqh_building_grid_urban_masonry",
            "fxqh_building_grid_urban_other",
            "fxqh_building_grid_urban_steel",
            "fxqh_building_grid_urban_steel_concrete",
            "fxqh_building_grid_urban_wood",
    };

    /**
     * 保存新版本
     *
     * @param dataVersionParam 版本参数
     */
    public String saveNewVersion(FxqhBuildingGridVersionSaveNewDataVersionParam dataVersionParam) throws StrategyFactoryException, BizException {
        dataVersionParam.setVersionCode(buildVersionCode(dataVersionParam.getDataRangeCountry()));
        this.insertVersionData(dataVersionParam);
//        // 保存解析出的数据
//        this.saveParseData(
//                dataVersionParam.getTempVersionCode(), dataVersionParam.getVersionCode(), dataVersionParam.getDataType());
        // 保存解析出的数据
        this.saveParseData(
                dataVersionParam.getTempVersionCode(), dataVersionParam.getVersionCode());
        BizThreadPoolManage.exeBizThreadPoolExecutor.execute(() -> {
            log.debug("刷新超图");
            for (String table : tables) {
                boolean bool = hypergraphService.getWorkspaceReload(table);
            }
        });
        return dataVersionParam.getVersionCode();
    }

    /**
     * 保存版本到数据库
     *
     * @param fxqhBuildingGridDataVersion
     */
    private void insertVersionData(FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion) {
        fxqhBuildingGridDataVersion.setId(IdUtil.getSnowflakeNextIdStr());
        fxqhBuildingGridDataVersion.setDelFlag(YNEnum.N.toString());
        Timestamp currTime = PlatformDateUtils.getCurrentTimestamp();
        fxqhBuildingGridDataVersion.setUploadTime(currTime);
        String currUid = PlatformSessionContext.getUserID();
        fxqhBuildingGridDataVersion.setUploadUser(currUid);
        fxqhBuildingGridDataVersion.setCreateTime(currTime);
        fxqhBuildingGridDataVersion.setCreateUser(PlatformSessionContext.getUserID());
        fxqhBuildingGridDataVersion.setUpdateTime(currTime);
        fxqhBuildingGridDataVersion.setUpdateUser(currUid);
        fxqhBuildingGridDataVersion.setDataRangeStr(this.buildDataRange(fxqhBuildingGridDataVersion));
        if (StringUtils.isBlank(fxqhBuildingGridDataVersion.getUpdateDesc())) {
            fxqhBuildingGridDataVersion.setUpdateDesc("无");
        }
        if("全国".equals(fxqhBuildingGridDataVersion.getDataRangeProvince())){
            fxqhBuildingGridDataVersion.setDataRangeProvince("");
            fxqhBuildingGridDataVersion.setDataRangeCity("");
            fxqhBuildingGridDataVersion.setDataRangeArea("");
        }
        if("全部".equals(fxqhBuildingGridDataVersion.getDataRangeCity())){
            fxqhBuildingGridDataVersion.setDataRangeCity("");
            fxqhBuildingGridDataVersion.setDataRangeArea("");
        }
        if("全部".equals(fxqhBuildingGridDataVersion.getDataRangeArea())){
            fxqhBuildingGridDataVersion.setDataRangeArea("");
        }
        fxqhBuildingGridVersionRepository.insert(fxqhBuildingGridDataVersion);
    }

    /**
     * 生成版本号
     *
     * <p>版本号规则：JZWWG+“数据范围代码”+“年月日”+“三位流水号” "数据范围编码：国家级数据01；省级数据02；市级数据03"
     *
     * @param dataRangeCode 数据范围 1国家级 2-省级 3-市级
     * @return
     */
    public synchronized String buildVersionCode(@NotNull int dataRangeCode) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String dataVersionCodeSerialNumber = valueOperations.get(DATA_VERSION_CODE_SERIAL_NUMBER_KEY);
        if (StringUtils.isBlank(dataVersionCodeSerialNumber)) {
            dataVersionCodeSerialNumber = "001";
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            String t = String.valueOf(Integer.parseInt(dataVersionCodeSerialNumber) + 1);
            for (int i = t.length(); i < 3; i++) {
                stringBuilder.append("0");
            }
            dataVersionCodeSerialNumber = stringBuilder.append(t).toString();
        }
        redisTemplate
                .opsForValue()
                .set(DATA_VERSION_CODE_SERIAL_NUMBER_KEY, dataVersionCodeSerialNumber);
        redisTemplate.expireAt(
                DATA_VERSION_CODE_SERIAL_NUMBER_KEY,
                Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.MAX).toInstant(ZoneOffset.of("+8"))));
        return DATA_VERSION_CODE_PREFIX
                + "0"
                + dataRangeCode
                + DateUtil.format(new Date(), "yyyyMMdd")
                + dataVersionCodeSerialNumber;
    }

    /**
     * 查询历史版本号
     *
     * @return
     */
    public List<String> getVersionCodeList(String dataType) {
        return fxqhBuildingGridVersionRepository.getVersionCodeList(dataType);
    }

    /**
     * 覆盖旧版本 删除旧版本，创建新版本，版本号使用之前的
     *
     * @param versionParam 数据版本
     */
    public String overwriteOldVersion(FxqhBuildingGridVersionSaveNewDataVersionParam versionParam) throws StrategyFactoryException, BizException {
        Date currTime = new Date();
        String currUid = PlatformSessionContext.getUserID();
        fxqhBuildingGridVersionRepository.delByVersionCode(versionParam.getVersionCode(), currTime, currUid); // 删除旧版本
        this.insertVersionData(versionParam); // 保存新版本
//        this.delBuildingGridDataByVersionCode(versionParam.getVersionCode(), currTime, currUid, versionParam.getDataType()); // 删除旧版本数据
        this.delBuildingGridDataByVersionCode(versionParam.getVersionCode(), currTime, currUid); // 删除旧版本数据
//        this.saveParseData(
//                versionParam.getTempVersionCode(),
//                versionParam.getVersionCode(), versionParam.getDataType()); // 将数据版本和业务数据进行绑定
        this.saveParseData(
                versionParam.getTempVersionCode(),
                versionParam.getVersionCode()); // 将数据版本和业务数据进行绑定
        return versionParam.getVersionCode();
    }

//    /**
//     * 删除建筑物公里网格数据
//     *
//     * @param versionCode
//     * @param currTime
//     * @param currUid
//     * @param dataTypeCode
//     */
//    private void delBuildingGridDataByVersionCode(String versionCode, Date currTime, String currUid, String dataTypeCode) throws StrategyFactoryException {
//        strategyFactory.getShpService(dataTypeCode).delByVersionCode(versionCode, currTime, currUid);
//    }

    /**
     * 删除建筑物公里网格数据
     *
     * @param versionCode
     * @param currTime
     * @param currUid
     */
    private void delBuildingGridDataByVersionCode(String versionCode, Date currTime, String currUid) throws StrategyFactoryException {
        fxqhBuildingGridService.delByVersionCode(versionCode, currTime, currUid);
    }

    /**
     * 根据id列表删除数据
     *
     * @param ids id列表
     */
    public void delByIds(List<String> ids) throws StrategyFactoryException {
        String currUid = PlatformSessionContext.getUserID();
        Date currTime = new Date();
        // 删除建筑网格数据
        for (String id : ids) {
            FxqhBuildingGridDataVersion dataVersion = this.getById(id);
            if (dataVersion != null) {
                this.delBuildingGridDataByVersionCode(dataVersion.getVersionCode(), currTime, currUid);
            }
        }
        // 删除版本数据
        fxqhBuildingGridVersionRepository.delByIds(ids, currUid, currTime);
        for (String id : ids) {
            redisTemplate.delete(FXQH_BUILDING_GRID_VERSION_DETAILS_CACHE + id);
        }
    }

    /**
     * 分页查询
     *
     * @param param
     * @return
     */
    public PageResult<FxqhBuildingGridDataVersionPageVo> page(FxqhBuildingGridDataVersionPageParam param) throws BizException {
        int tPNum = param.getPage();
        param.setPage(param.getRows() * (Math.max(param.getPage(), 1) - 1));
        // 构建上传人用户名查询
        if (StringUtils.isNotBlank(param.getUploadUsername())) {
            param.setUploadUserIds(
                    StringUtils.join(
                            this.getLikeUsernameUploadUserId(param.getUploadUsername()),
                            "','"));
        }
        List<String> idList = fxqhBuildingGridVersionRepository.selectList(param);
        List<FxqhBuildingGridDataVersion> list = new ArrayList<>();
        for (String id : idList) {
            list.add(this.getById(id));
        }
        List<FxqhBuildingGridDataVersionPageVo> voList = this.entity2FxqhBuildingGridDataVersionPageVoForList(list);
        Integer total = fxqhBuildingGridVersionRepository.selectCount(param);
        return new PageResult<>(
                tPNum,
                param.getRows(),
                PageUtil.totalPage(total, param.getRows()),
                total,
                voList);
    }

    /**
     * 实体转FxqhBuildingGridDataVersionPageVo
     *
     * @param list
     * @return
     */
    private List<FxqhBuildingGridDataVersionPageVo> entity2FxqhBuildingGridDataVersionPageVoForList(List<FxqhBuildingGridDataVersion> list) throws BizException {
        List<FxqhBuildingGridDataVersionPageVo> restList = new ArrayList<>();
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSON.parse((String) redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        for (FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion : list) {
            //restList.add(this.entity2FxqhBuildingGridDataVersionPageVo(fxqhBuildingGridDataVersion,areaIdCodeMap));
            FxqhBuildingGridDataVersionPageVo vo = new FxqhBuildingGridDataVersionPageVo();
            BeanUtils.copyProperties(fxqhBuildingGridDataVersion, vo);
            vo.setUploadUserId(fxqhBuildingGridDataVersion.getUploadUser());
            SUser user = this.getUser(fxqhBuildingGridDataVersion.getUploadUser());
            if (user != null) {
                vo.setUploadUser(user.getUserName());
            }
            vo.setUploadTime(fxqhBuildingGridDataVersion.getUploadTime());
            vo.setDataRange(fxqhBuildingGridDataVersion.getDataRangeStr());
            String id = "";
            if(StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataRangeProvince())){
                id+=(fxqhBuildingGridDataVersion.getDataRangeProvince()+",");
            }
            if(StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataRangeCity())){
                id+=(fxqhBuildingGridDataVersion.getDataRangeCity()+",");
            }
            if(StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataRangeArea())){
                id+=(fxqhBuildingGridDataVersion.getDataRangeArea()+",");
            }
            vo.setDataFileList(this.getAttachmentList(fxqhBuildingGridDataVersion.getDataFileIds()));
            vo.setAttachmentList(this.getAttachmentList(fxqhBuildingGridDataVersion.getAttachmentIds()));
            vo.setDataRangeProvince(fxqhBuildingGridDataVersion.getDataRangeProvince());
            vo.setDataRangeCity(fxqhBuildingGridDataVersion.getDataRangeCity());
            vo.setDataRangeCountry(fxqhBuildingGridDataVersion.getDataRangeCountry());
            if(id.endsWith(",")){
                id = id.substring(0,id.length()-1);
            }
            String province = "";
            String city = "";
            String area = "";
            if(StringUtils.isNotBlank(id)){
                String areaName = sysAreaService.getAreaNameByAreaId(id);
                if(StringUtils.isNotBlank(areaName)){
                    String[] split = areaName.split(",");
                    if(split.length==3){
                        area = split[2];
                        city = split[1];
                    }else if(split.length==2){
                        city = split[1];
                    }
                    province = split[0];
                }
            }
            vo.setProvinceName(province);
            vo.setCityName(city);
            vo.setCountyName(area);
            restList.add(vo);
        }
        return restList;
    }

    /**
     * 实体转FxqhBuildingGridDataVersionPageVo
     *
     * @param fxqhBuildingGridDataVersion
     * @return
     */
    private FxqhBuildingGridDataVersionPageVo entity2FxqhBuildingGridDataVersionPageVo(FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion,Map<String, String> areaIdCodeMap) throws BizException {
        FxqhBuildingGridDataVersionPageVo vo = new FxqhBuildingGridDataVersionPageVo();
        BeanUtils.copyProperties(fxqhBuildingGridDataVersion, vo);
        vo.setUploadUserId(fxqhBuildingGridDataVersion.getUploadUser());
        SUser user = this.getUser(fxqhBuildingGridDataVersion.getUploadUser());
        if (user != null) {
            vo.setUploadUser(user.getUserName());
        }
        vo.setDataRange(fxqhBuildingGridDataVersion.getDataRangeStr());
        vo.setDataFileList(this.getAttachmentList(fxqhBuildingGridDataVersion.getDataFileIds()));
        vo.setAttachmentList(this.getAttachmentList(fxqhBuildingGridDataVersion.getAttachmentIds()));
        vo.setProvinceName(sysAreaCacheService.getAreaNameByAreaId(fxqhBuildingGridDataVersion.getDataRangeProvince()));
        vo.setCityName(sysAreaCacheService.getAreaNameByAreaId(fxqhBuildingGridDataVersion.getDataRangeCity()));
        vo.setCountyName(sysAreaCacheService.getAreaNameByAreaId(fxqhBuildingGridDataVersion.getDataRangeArea()));
        String code = null;
        if (areaIdCodeMap==null||areaIdCodeMap.size()<1) {
            if ("1".equals(fxqhBuildingGridDataVersion.getDataRangeCountry()+"")){
                code = sysAreaService.getDivisionCodeById(fxqhBuildingGridDataVersion.getDataRangeProvince());
            }else if ("2".equals(fxqhBuildingGridDataVersion.getDataRangeCountry()+"")){
                code = sysAreaService.getDivisionCodeById(fxqhBuildingGridDataVersion.getDataRangeCity());
            }else {
                code = sysAreaService.getDivisionCodeById(fxqhBuildingGridDataVersion.getDataRangeArea());
            }
        }else {
            if ("1".equals(fxqhBuildingGridDataVersion.getDataRangeCountry()+"")){
                code = areaIdCodeMap.get(fxqhBuildingGridDataVersion.getDataRangeProvince());
            }else if ("2".equals(fxqhBuildingGridDataVersion.getDataRangeCountry()+"")){
                code = areaIdCodeMap.get(fxqhBuildingGridDataVersion.getDataRangeCity());
            }else {
                code = areaIdCodeMap.get(fxqhBuildingGridDataVersion.getDataRangeArea());
            }
        }
        String geom = jcsjRestManager.getGeomByCode(code,fxqhBuildingGridDataVersion.getDataRangeCountry()+"");
        vo.setGeomText(geom);
        return vo;
    }

    /**
     * 查询附件信息
     *
     * @param attachIdStr
     * @return
     */
    private List<FxqhBuildingGridDataVersionPageVo.Attachment> getAttachmentList(String attachIdStr) {
        if (StringUtils.isNotBlank(attachIdStr)) {
            String[] dataFileIds = attachIdStr.split(",");
            List<FxqhBuildingGridDataVersionPageVo.Attachment> dataFileList = new ArrayList<>();
            List<FxqhBuildingGridDataVersionPageVo.Attachment> newDataFileList = new ArrayList<>();
            for (String dataFileId : dataFileIds) {
                AttachmentInfoEntity attach = attachmentInfoService.getAttach(dataFileId);
                if (null != attach) {
                    FxqhBuildingGridDataVersionPageVo.Attachment dataFile = new FxqhBuildingGridDataVersionPageVo.Attachment();
                    dataFile.setId(attach.getAttachId());
                    dataFile.setName(attach.getAttachName());
                    dataFileList.add(dataFile);
                }
            }
            //文件名排序,前缀相同的放一起
            Map<String, List<FxqhBuildingGridDataVersionPageVo.Attachment>> collect = dataFileList.stream().collect(Collectors.groupingBy(file -> {
                int laseDotIndex = file.getName().lastIndexOf("_");
                return laseDotIndex != -1 ? file.getName().substring(0, laseDotIndex):file.getName();
            }));
            collect.forEach((k,v)->{
                newDataFileList.addAll(v);
            });
            return newDataFileList;
        }
        return null;
    }

    /**
     * 查询相似用户名的版本表上传人用户id
     *
     * @param username
     * @return
     */
    private List<String> getLikeUsernameUploadUserId(String username) {
        List<SUser> userCache = this.getUserCacheList();
        List<String> likeUserIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userCache)) {
            for (SUser sUser : userCache) {
                if (sUser.getUserName().contains(username)) {
                    likeUserIds.add(sUser.getUserId());
                }
            }
        }
        if (CollectionUtils.isEmpty(likeUserIds)) {
            List<String> userIdList = fxqhBuildingGridVersionRepository.selectAllUploadUserId();
            for (String userId : userIdList) {
                SUser user = this.getUser(userId);
                if (user != null && user.getUserName().contains(username)) {
                    likeUserIds.add(user.getUserId());
                }
            }
            if (likeUserIds.isEmpty()) {
                likeUserIds.add(UUID.randomUUID() + "xxx");
            }
        }
        return likeUserIds;
    }

    /**
     * 构建数据范围文字显示
     *
     * @param fxqhBuildingGridDataVersion 查询接口查询参数，数据版本原实体
     */
    private String buildDataRange(FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion) {
        if (fxqhBuildingGridDataVersion.getDataRangeCountry() == 0) {
            return "-";
        }
        StringBuilder stringBuilder = new StringBuilder();
        String prefix = fxqhBuildingGridDataVersion.getDataRangeCountry() == 1 ? "国家级" : "省级";
        if (StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataRangeProvince()) && !fxqhBuildingGridDataVersion.getDataRangeProvince().equals("全国")) {
            String provinceName =
                    this.getAreaNameByAreaIdFromCache(
                            fxqhBuildingGridDataVersion.getDataRangeProvince()); // 省
            if (StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataRangeCity()) && !"全国".equals(fxqhBuildingGridDataVersion.getDataRangeCity())) {
                String cityName =
                        this.getAreaNameByAreaIdFromCache(
                                fxqhBuildingGridDataVersion.getDataRangeCity()); // 市
                if (StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataRangeArea()) && !"全国".equals(fxqhBuildingGridDataVersion.getDataRangeArea())) {
                    String areaName = "全部".equals(fxqhBuildingGridDataVersion.getDataRangeArea()) ? "" :
                            this.getAreaNameByAreaIdFromCache(
                                    fxqhBuildingGridDataVersion.getDataRangeArea()); // 区县
                    stringBuilder
                            .append(prefix)
                            .append("（")
                            .append(provinceName)
                            .append(cityName)
                            .append(areaName)
                            .append("）");
                } else {
                    stringBuilder
                            .append(prefix)
                            .append("（")
                            .append(provinceName)
                            .append(cityName)
                            .append("）");
                }
            } else {
                stringBuilder.append(prefix).append("（").append(provinceName).append("）");
            }
        } else {
            stringBuilder.append(prefix);
        }
        return stringBuilder.toString();
    }

    @Deprecated
    public void dataExport(HttpServletResponse response, List<String> idList) throws IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType(
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader(
                "Content-Disposition", "attachment;filename=" + System.currentTimeMillis() + ".xlsx");
        response.setContentType("application/octet-stream;charset=utf-8");
        List<FxqhBuildingGridDataVersion> list = fxqhBuildingGridVersionRepository.selectByIds(idList);
        List<SysDataVersionExportModel> exportModels = new ArrayList<>();
        for (FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion : list) {
            SysDataVersionExportModel sysDataVersionExportModel = new SysDataVersionExportModel();
            sysDataVersionExportModel.setVersionTime(
                    DateUtil.format(fxqhBuildingGridDataVersion.getVersionTime(), "yyyy-MM-dd"));
            sysDataVersionExportModel.setVersionCode(fxqhBuildingGridDataVersion.getVersionCode());
            sysDataVersionExportModel.setDataName(fxqhBuildingGridDataVersion.getDataName());
            sysDataVersionExportModel.setDataRange(fxqhBuildingGridDataVersion.getDataRangeStr());
            sysDataVersionExportModel.setUploadTime(
                    DateUtil.format(fxqhBuildingGridDataVersion.getUpdateTime(), "yyyy-MM-dd"));
            sysDataVersionExportModel.setUploadUser(
                    this.getUsername(fxqhBuildingGridDataVersion.getUploadUser()));
            sysDataVersionExportModel.setVersionDesc(fxqhBuildingGridDataVersion.getVersionDesc());
            sysDataVersionExportModel.setDataDesc(fxqhBuildingGridDataVersion.getDataDesc());
            sysDataVersionExportModel.setUpdateDesc(fxqhBuildingGridDataVersion.getUpdateDesc());
            exportModels.add(sysDataVersionExportModel);
        }
        ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter(true);
        writer.addHeaderAlias("versionTime", "版本时间");
        writer.addHeaderAlias("versionCode", "版本号");
        writer.addHeaderAlias("dataName", "数据名称");
        writer.addHeaderAlias("dataRange", "数据范围");
        writer.addHeaderAlias("uploadTime", "上传时间");
        writer.addHeaderAlias("uploadUser", "上传人");
        writer.addHeaderAlias("versionDesc", "版本说明");
        writer.addHeaderAlias("dataDesc", "数据说明");
        writer.addHeaderAlias("updateDesc", "更新说明");
        writer.setOnlyAlias(true);
        writer.write(exportModels, true);
        setSizeColumn(writer.getSheet(), 8);
        writer.flush(outputStream, true);
        writer.close();
        IoUtil.close(outputStream);
    }

    /**
     * 自适应宽度(中文支持)
     *
     * @param sheet sheet
     * @param size  因为for循环从0开始，size值为 列数-1
     */
    private static void setSizeColumn(Sheet sheet, int size) {
        for (int columnNum = 0; columnNum <= size; columnNum++) {
            int columnWidth = sheet.getColumnWidth(columnNum) / 256;
            for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
                Row currentRow;
                //当前行未被使用过
                if (sheet.getRow(rowNum) == null) {
                    currentRow = sheet.createRow(rowNum);
                } else {
                    currentRow = sheet.getRow(rowNum);
                }
                if (currentRow.getCell(columnNum) != null) {
                    Cell currentCell = currentRow.getCell(columnNum);
                    if (currentCell.getCellType() == CellType.STRING) {
                        int length = currentCell.getStringCellValue().getBytes().length;
                        if (columnWidth < length) {
                            columnWidth = length;
                        }
                    }
                }
            }
            sheet.setColumnWidth(columnNum, columnWidth * 256);
        }
    }

    private DictItemEntity getDataTypeEntity(String dataTypeCode) {
        if (dataTypeCode == null) {
            return null;
        }
        return dictItemService.getDictItemByDictCodeAndItemCode(DICT_CODE, dataTypeCode);
    }

    private String getDataTypeName(String dataTypeCode) {
        if (dataTypeCode == null) {
            return null;
        }
        DictItemEntity dictItemByDictCodeAndItemCode = dictItemService.getDictItemByDictCodeAndItemCode(DICT_CODE, dataTypeCode);
        return dictItemByDictCodeAndItemCode == null ? null : dictItemByDictCodeAndItemCode.getDictItemName();
    }

    public void dataExport(HttpServletResponse response, List<String> idList, boolean exportAttach)
            throws IOException {
        List<SysDataVersionExportModel> exportModels = new ArrayList<>();
        List<FxqhBuildingGridDataVersion> list = new ArrayList<>();
        for (String id : idList) {
            FxqhBuildingGridDataVersion dataVersion = this.getById(id);
            if (dataVersion != null) {
                list.add(dataVersion);
                SysDataVersionExportModel sysDataVersionExportModel = new SysDataVersionExportModel();
                sysDataVersionExportModel.setVersionTime(
                        DateUtil.format(dataVersion.getVersionTime(), "yyyy-MM-dd"));
                sysDataVersionExportModel.setVersionCode(dataVersion.getVersionCode());
                sysDataVersionExportModel.setDataName(dataVersion.getDataName());
                sysDataVersionExportModel.setDataRange(dataVersion.getDataRangeStr());
                sysDataVersionExportModel.setUploadTime(
                        DateUtil.format(dataVersion.getUpdateTime(), "yyyy-MM-dd"));
                sysDataVersionExportModel.setUploadUser(
                        this.getUsername(dataVersion.getUploadUser()));
                sysDataVersionExportModel.setVersionDesc(dataVersion.getVersionDesc());
                sysDataVersionExportModel.setDataDesc(dataVersion.getDataDesc());
                sysDataVersionExportModel.setUpdateDesc(dataVersion.getUpdateDesc());
//                sysDataVersionExportModel.setDataType(getDataTypeName(dataVersion.getDataType()));
                exportModels.add(sysDataVersionExportModel);
            }
        }
        List<ExcelUtils.ExcelAlias> aliasList = new ArrayList<>();
        aliasList.add(ExcelUtils.alias("versionTime", "版本时间"));
        aliasList.add(ExcelUtils.alias("versionCode", "版本号"));
        aliasList.add(ExcelUtils.alias("dataName", "数据名称"));
        aliasList.add(ExcelUtils.alias("dataType", "数据类别"));
        aliasList.add(ExcelUtils.alias("dataRange", "数据范围"));
        aliasList.add(ExcelUtils.alias("uploadTime", "上传时间"));
        aliasList.add(ExcelUtils.alias("uploadUser", "上传人"));
        aliasList.add(ExcelUtils.alias("versionDesc", "版本说明"));
        aliasList.add(ExcelUtils.alias("dataDesc", "数据说明"));
        aliasList.add(ExcelUtils.alias("updateDesc", "更新说明"));
        if (exportAttach) {
            this.exportDataVersion2Zip(exportModels, aliasList, list, response);
        } else {
            ExcelUtils.exportExcel(
                    exportModels, aliasList, "data_version_" + System.currentTimeMillis(), response);
        }
    }

    private void exportDataVersion2Zip(
            List<SysDataVersionExportModel> exportModels,
            List<ExcelUtils.ExcelAlias> alias,
            Iterable<? extends FxqhBuildingGridDataVersion> list,
            HttpServletResponse response)
            throws FileNotFoundException {
        List<ZipUtils.ZipExportWeb> fileList = new ArrayList<>();
        File excelFile =
                ExcelUtils.createExcel(
                        exportModels,
                        alias,
                        ResourceUtils.getURL("classpath:").getPath()
                                + File.separator
                                + "cache_file"
                                + File.separator
                                + System.currentTimeMillis()
                                + ".xlsx");
        fileList.add(new ZipUtils.ZipExportWeb(excelFile, null));
        for (FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion : list) {
            String attachmentIds = fxqhBuildingGridDataVersion.getAttachmentIds();
            if (StringUtils.isNotBlank(attachmentIds)) {
                String[] idArr = attachmentIds.split(",");
                for (String id : idArr) {
                    String attachPath = attachmentInfoService.getAttach(id).getAttachPath();
                    fileList.add(
                            new ZipUtils.ZipExportWeb(
                                    new File(localDir + File.separator + attachPath),
                                    fxqhBuildingGridDataVersion.getVersionCode()));
                }
            }
            String dataFileIds = fxqhBuildingGridDataVersion.getDataFileIds();
            if (StringUtils.isNotBlank(dataFileIds)) {
                String[] idArr = dataFileIds.split(",");
                for (String id : idArr) {
                    String attachPath = attachmentInfoService.getAttach(id).getAttachPath();
                    fileList.add(
                            new ZipUtils.ZipExportWeb(
                                    new File(localDir + File.separator + attachPath),
                                    fxqhBuildingGridDataVersion.getVersionCode()));
                }
            }
        }
        ZipUtils.exportZip(fileList, "data_version_" + System.currentTimeMillis(), response);
        FileUtil.del(excelFile);
    }

//    /**
//     * 查询数据视图
//     *
//     * @param param 必填参数有版本号,数据类别代码
//     * @return
//     */
//    public QueryByVersionVo<?> queryDataView(BasePageParam param) throws StrategyFactoryException {
//        FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion = fxqhBuildingGridVersionRepository.selectByVersionCode(param.getDataVersion());
//        return strategyFactory.getShpService(fxqhBuildingGridDataVersion.getDataType()).queryDataByVersionCode(
//                QueryByVersionParam.builder()
//                        .versionCode(param.getDataVersion())
//                        .page(param.getPage())
//                        .rows(param.getRows())
//                        .build());
//    }

//    /**
//     * 判断是否已有同类数据 判断依据：如果选择的一样的数据类别且一样的数据范围
//     *
//     * @param sysDataVersionSameTypeDataExistParam
//     * @return
//     */
//    public Map<String, Object> hasDuplicateData(
//            SysDataVersionSameTypeDataExistParam sysDataVersionSameTypeDataExistParam) {
//        String versionCode =
//                fxqhBuildingGridVersionRepository.hasDuplicateData(sysDataVersionSameTypeDataExistParam);
//        boolean isExist = StringUtils.isNotBlank(versionCode);
//        return new HashMap<String, Object>() {
//            {
//                put("isExist", isExist);
//                if (isExist) {
//                    put("tipMsg", "本系统已有同类遥感数据（版本号为" + versionCode + "），是否作为新版本数据进行上传？");
//                    put("versionCode", versionCode);
//                }
//            }
//        };
//    }

    /**
     * 保存元数据信息
     *
     * @param param
     */
    public void saveMetaDataInfo(VersionSaveMetaDataParam param) {
        FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion =
                fxqhBuildingGridVersionRepository.selectByVersionCode(param.getVersionCode());
        if (fxqhBuildingGridDataVersion == null) {
            return;
        }
        param.setUpdateTime(new Date());
        param.setUpdateUser(PlatformSessionContext.getUserID());
        fxqhBuildingGridVersionRepository.saveMetaDataInfo(param);
        redisTemplate.delete(
                FXQH_BUILDING_GRID_VERSION_DETAILS_CACHE + fxqhBuildingGridDataVersion.getId());
    }

    /**
     * 根据版本号获取元数据信息
     *
     * @param versionCode
     * @return
     */
    public VersionMetaDataVo getMetaDataByVersionCode(String versionCode) {
        FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion =
                fxqhBuildingGridVersionRepository.selectByVersionCode(versionCode);
        VersionMetaDataVo sysDataVersionGetByVersionCodeVo =
                VersionMetaDataVo.builder()
                        .versionCode(versionCode)
                        .coordinateSystemType("大地坐标系")
                        .coordinateSystemName("2000国家大地坐标系")
                        .coordinateSystemEnName("CGCS2000")
                        .build();
        BeanUtils.copyProperties(fxqhBuildingGridDataVersion, sysDataVersionGetByVersionCodeVo);
        sysDataVersionGetByVersionCodeVo.setUploadUser(this.getUsername(fxqhBuildingGridDataVersion.getUploadUser()));
        sysDataVersionGetByVersionCodeVo.setIsSpatialData(1);
//        if (StringUtils.isNotBlank(fxqhBuildingGridDataVersion.getDataType())) {
//            DictItemEntity dict = dictItemService.getDictItemByDictCodeAndItemCode(DICT_CODE, fxqhBuildingGridDataVersion.getDataType());
//            if (dict != null) {
//                sysDataVersionGetByVersionCodeVo.setDataType(dict.getDictItemName());
//            }
//        }
        return sysDataVersionGetByVersionCodeVo;
    }

//    /**
//     * 综合检索
//     *
//     * @param param 综合检索查询条件
//     * @return
//     */
//    public PageResult<SysDataVersionPageVo> synthesisSearch(
//            SysDataVersionSynthesisSearchParam param) {
//        int tPNum = param.getPage();
//        param.setPage(param.getRows() * (Math.max(param.getPage(), 1) - 1));
//        List<FxqhBuildingGridDataVersion> list =
//                fxqhBuildingGridVersionRepository.synthesisSearch(param);
//        List<SysDataVersionPageVo> restList = this.buildSysDataVersionPageVoList(list);
//        Integer total = fxqhBuildingGridVersionRepository.countForSynthesisSearch(param);
//        return new PageResult<>(
//                tPNum, param.getRows(), PageUtil.totalPage(total, param.getRows()), total, restList);
//    }

//    private List<SysDataVersionPageVo> buildSysDataVersionPageVoList(
//            List<FxqhBuildingGridDataVersion> list) {
//        List<SysDataVersionPageVo> restList = new ArrayList<>();
//        for (FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion : list) {
//            restList.add(this.buildSysDataVersionPageVo(fxqhBuildingGridDataVersion));
//        }
//        return restList;
//    }

//    /**
//     * 构建SysDataVersionPageVo
//     *
//     * @param fxqhBuildingGridDataVersion
//     * @return
//     */
//    private SysDataVersionPageVo buildSysDataVersionPageVo(
//            FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion) {
//        SysDataVersionPageVo sysDataVersionPageVo =
//                new SysDataVersionPageVo() {
//                    {
//                        setId(fxqhBuildingGridDataVersion.getId());
//                        setVersionCode(fxqhBuildingGridDataVersion.getVersionCode());
//                        setVersionTime(fxqhBuildingGridDataVersion.getVersionTime());
//                        setVersionDesc(fxqhBuildingGridDataVersion.getVersionDesc());
//                        setUploadUserId(fxqhBuildingGridDataVersion.getUploadUser());
//                        setUploadUser(
//                                commonService.getUser(fxqhBuildingGridDataVersion.getUploadUser()).getUserName());
//                        setUploadTime(fxqhBuildingGridDataVersion.getUploadTime());
//                        setUpdateDesc(fxqhBuildingGridDataVersion.getUpdateDesc());
//                        setDataName(fxqhBuildingGridDataVersion.getDataName());
//                        setDataDesc(fxqhBuildingGridDataVersion.getDataDesc());
//                        DictItemEntity leve2 =
//                                dictItemService.getDictItem(fxqhBuildingGridDataVersion.getDataTypeLevel2());
//                        DictItemEntity leve3 =
//                                dictItemService.getDictItem(fxqhBuildingGridDataVersion.getDataTypeLevel3());
//                        setDataType(leve2.getDictItemName());
//                        setDataTypeLevel2Code(leve2.getDictItemCode());
//                        setDataTypeLevel3Code(leve3.getDictItemCode());
//                        setDataRange(fxqhBuildingGridDataVersion.getDataRangeStr());
//                    }
//                };
//        sysDataVersionPageVo.setDataFileList(
//                this.getAttachmentList(fxqhBuildingGridDataVersion.getDataFileIds()));
//        sysDataVersionPageVo.setAttachmentList(
//                this.getAttachmentList(fxqhBuildingGridDataVersion.getAttachmentIds()));
//        return sysDataVersionPageVo;
//    }

//    /**
//     * 查询临时上传的文件根据id
//     *
//     * @param id       临时数据id
//     * @param typeCode 存储表名
//     * @param show     0为excel,1为图片
//     * @return
//     */
//    public RestResponse queryTemporaryUploadById(String id, String typeCode, Integer show) {
//        ArrayList<AttachmentInfoEntity> list = new ArrayList<>();
//        // 根据typeCode找对应的service
//        switch (Objects.requireNonNull(getPgSQLTableDictEnum(typeCode))) {
//            // 只有有图片烈度分布示意图,2000年以来的震害与救灾案例（属性表）
//            case JC_DISASTER_CASE:
//                String jcDisasterCaseIds = jcDisasterCaseService.queryTemporaryUploadById(id);
//                if (!StringUtils.isNotBlank(jcDisasterCaseIds)) {
//                    return RestResponse.succeed(null);
//                }
//                String[] split1 = jcDisasterCaseIds.split(",");
//                for (String s : split1) {
//                    AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(s);
//                    list.add(attachmentInfoEntity);
//                }
//                return RestResponse.succeed(list);
//            // 有图片字段和excel字段
//            case JC_EARTHQUAKE_DAMAGE_SURVEY:
//                String jcEarthquakeDamageIds =
//                        jcEarthquakeDamageSurveyService.queryTemporaryUploadById(id, show);
//                if (!StringUtils.isNotBlank(jcEarthquakeDamageIds)) {
//                    return RestResponse.succeed(null);
//                }
//                String[] split = jcEarthquakeDamageIds.split(",");
//                for (String s : split) {
//                    AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(s);
//                    list.add(attachmentInfoEntity);
//                }
//                return RestResponse.succeed(list);
//            default:
//                return RestResponse.fail("数据类别不存在");
//        }
//    }

//    /**
//     * 保存临时上传的文件根据id
//     *
//     * @param id       id
//     * @param ids      文件id以,分割
//     * @param typeCode 存储表名
//     * @param show
//     * @return
//     */
//    public RestResponse saveTemporaryUploadById(
//            String id, String ids, String typeCode, Integer show) {
//        // 根据typeCode找对应的service
//        switch (Objects.requireNonNull(getPgSQLTableDictEnum(typeCode))) {
//            // 只有有图片烈度分布示意图,2000年以来的震害与救灾案例（属性表）
//            case JC_DISASTER_CASE:
//                JcDisasterCase jcDisasterCase = new JcDisasterCase();
//                jcDisasterCase.setJdcId(id);
//                jcDisasterCase.setIsolineMap(ids);
//                try {
//                    jcDisasterCaseService.updateFileById(jcDisasterCase);
//                    TemporaryUploadVo temporaryUploadVo = new TemporaryUploadVo();
//                    temporaryUploadVo.setPicture("2");
//                    temporaryUploadVo.setExcel("1");
//                    return RestResponse.succeed(temporaryUploadVo);
//                } catch (Exception e) {
//                    log.error("添加失败!", e);
//                    return RestResponse.fail(e.getMessage());
//                }
//                // 有图片字段和excel字段
//            case JC_EARTHQUAKE_DAMAGE_SURVEY:
//                JcEarthquakeDamageSurvey jcEarthquakeDamageSurvey = new JcEarthquakeDamageSurvey();
//                jcEarthquakeDamageSurvey.setJedsId(id);
//                TemporaryUploadVo temporaryUploadVo = new TemporaryUploadVo();
//                if (show.equals(1)) {
//                    // 图片
//                    jcEarthquakeDamageSurvey.setJedsZhzp(ids);
//                    // 文件是否上传,1是未上传 2是已上传
//                    temporaryUploadVo.setPicture("1");
//                    // 图片是否上传,1是未上传 2是已上传
//                    temporaryUploadVo.setExcel("2");
//                } else {
//                    // 报表
//                    jcEarthquakeDamageSurvey.setAttachment(ids);
//                    // 文件是否上传,1是未上传 2是已上传
//                    temporaryUploadVo.setPicture("2");
//                    // 图片是否上传,1是未上传 2是已上传
//                    temporaryUploadVo.setExcel("1");
//                }
//                try {
//                    jcEarthquakeDamageSurveyService.updateFileById(jcEarthquakeDamageSurvey);
//                    return RestResponse.succeed(temporaryUploadVo);
//                } catch (Exception e) {
//                    log.error("添加失败!", e);
//                    return RestResponse.fail(e.getMessage());
//                }
//            default:
//                return RestResponse.fail("数据类别不存在");
//        }
//    }

//    /**
//     * 该版本的数据是否被其他系统使用
//     *
//     * @param versionCode
//     * @return
//     */
//    public Map<String, Object> dataVersionIsUse(String versionCode) {
//        List<SysSubsystemUseRecord> sysUseRecords = sysUseRecordRepo.selectByVersionCode(versionCode);
//        return new HashMap<String, Object>() {
//            {
//                put("isUse", !sysUseRecords.isEmpty());
//                if (!sysUseRecords.isEmpty()) {
//                    for (SysSubsystemUseRecord sysUseRecord : sysUseRecords) {
//                        put(
//                                "useSysList",
//                                new HashMap<String, Object>() {
//                                    {
//                                        put(
//                                                "sysName",
//                                                sysSubsystemService.selectById(sysUseRecord.getSubsystemId()).getName());
//                                        put("operation", sysUseRecord.getOperation());
//                                    }
//                                });
//                    }
//                    put(
//                            "message",
//                            sysUseRecords.stream()
//                                    .map(o -> sysSubsystemService.selectById(o.getSubsystemId()).getName())
//                                    .collect(Collectors.joining("、"))
//                                    + "子系统使用了该版本数据产生了"
//                                    + sysUseRecords.stream()
//                                    .map(o -> SubsystemUseOpEnum.getByCode(o.getOperation()).getName())
//                                    .collect(Collectors.joining("、"))
//                                    + "结果，若继续"
//                                    + sysUseRecords.stream()
//                                    .map(o -> SubsystemUseOpEnum.getByCode(o.getOperation()).getName())
//                                    .collect(Collectors.joining("、"))
//                                    + "结果无效，需重新计算，是否继续？");
//                }
//            }
//        };
//    }

//    /**
//     * 保存临时数据,根据版本号
//     *
//     * @param sourceVersionCode 临时版本号
//     * @param targetVersionCode 真正的版本号
//     * @param dataTypeCode      建筑物公里网格类型码
//     * @return
//     */
//    public void saveParseData(String sourceVersionCode, String targetVersionCode, String dataTypeCode) throws StrategyFactoryException, BizException {
//        strategyFactory.getShpService(dataTypeCode).saveParseData(sourceVersionCode, targetVersionCode);
//    }

    /**
     * 保存临时数据,根据版本号
     *
     * @param sourceVersionCode 临时版本号
     * @param targetVersionCode 真正的版本号
     *                          //     * @param dataTypeCode      建筑物公里网格类型码
     * @return
     */
    public void saveParseData(String sourceVersionCode, String targetVersionCode) throws StrategyFactoryException, BizException {
//        strategyFactory.getShpService(dataTypeCode).saveParseData(sourceVersionCode, targetVersionCode);
        fxqhBuildingGridService.saveParseData(sourceVersionCode, targetVersionCode);
    }

    /**
     * 解析shp文件返回shp数据
     *
     * @param fileMap 文件
     * @return
     */
    public ParsingResult getShpData(Map<String, File> fileMap) throws Exception {
        // .prj结尾用来校验是否为2000坐标系
        String prj = fileMap.get(".prj") == null ? StringUtils.EMPTY : fileMap.get(".prj").getPath();
        // .cpg文件用来获得编码格式,例如utf-8
        String cpg = fileMap.get(".cpg") == null ? StringUtils.EMPTY : fileMap.get(".cpg").getPath();
        // .shp文件用来获得数据
        String shp = fileMap.get(".shp") == null ? StringUtils.EMPTY : fileMap.get(".shp").getPath();
        return ShpAnalyticUtil.analytic(prj, cpg, shp);
    }

    /**
     * 解析shp并存储临时数据
     *
     * @param fileIds shp文件id
     * @return
     */
    public VersionParseFileVo parseShp(String fileIds) throws Exception {
        VersionParseFileVo vo = new VersionParseFileVo();
        String tempVersionCode = IdUtil.simpleUUID();
        Map<String, List<AttachmentInfoEntity>> attachMap = new HashMap<>();

        for (String fileId : fileIds.split(",")) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(fileId);
            String fileNamePrefix = FileUtil.getPrefix(attach.getAttachName()).split("_")[0];
            List<AttachmentInfoEntity> attachmentInfoEntities = attachMap.get(fileNamePrefix);
            if (attachmentInfoEntities != null) {
                attachmentInfoEntities.add(attach);
            } else {
                attachmentInfoEntities = new ArrayList<>();
                attachmentInfoEntities.add(attach);
            }
            attachMap.put(fileNamePrefix, attachmentInfoEntities);
        }
        if (attachMap.keySet().size() < 13) {
            throw new ShpFieldException("13类格网的shp文件需要全部上传，并且文件需要根据要求命名");
        }
        List<String> gridTypeFileFormatList = Arrays.asList(GRID_TYPE_FILE_FORMAT);
        for (String fileNamePrefix : attachMap.keySet()) {
            if (!gridTypeFileFormatList.contains(fileNamePrefix)) {
                throw new ShpFieldException("文件命名错误:" + fileNamePrefix);
            }
        }
        VersionParseFileVo vo1 = parseSaveGrid(attachMap.get("城镇其他结构房屋格网"), "城镇其他结构房屋格网", tempVersionCode, fxqhBuildingGridUrbanOtherService);
        VersionParseFileVo vo2 = parseSaveGrid(attachMap.get("城镇钢结构房屋格网"), "城镇钢结构房屋格网", tempVersionCode, fxqhBuildingGridUrbanSteelService);
        VersionParseFileVo vo3 = parseSaveGrid(attachMap.get("城镇木结构房屋格网"), "城镇木结构房屋格网", tempVersionCode, fxqhBuildingGridUrbanWoodService);
        VersionParseFileVo vo4 = parseSaveGrid(attachMap.get("城镇钢混结构房屋格网"), "城镇钢混结构房屋格网", tempVersionCode, fxqhBuildingGridUrbanSteelConcreteService);
        VersionParseFileVo vo5 = parseSaveGrid(attachMap.get("城镇砌体结构房屋格网"), "城镇砌体结构房屋格网", tempVersionCode, fxqhBuildingGridUrbanMasonryService);
        VersionParseFileVo vo6 = parseSaveGrid(attachMap.get("农村木竹结构房屋格网"), "农村木竹结构房屋格网", tempVersionCode, fxqhBuildingGridRuralWoodBambooService);
        VersionParseFileVo vo7 = parseSaveGrid(attachMap.get("农村钢结构房屋格网"), "农村钢结构房屋格网", tempVersionCode, fxqhBuildingGridRuralSteelService);
        VersionParseFileVo vo8 = parseSaveGrid(attachMap.get("农村钢混结构房屋格网"), "农村钢混结构房屋格网", tempVersionCode, fxqhBuildingGridRuralSteelConcreteService);
        VersionParseFileVo vo9 = parseSaveGrid(attachMap.get("农村其他结构房屋格网"), "农村其他结构房屋格网", tempVersionCode, fxqhBuildingGridRuralOtherService);
        VersionParseFileVo vo10 = parseSaveGrid(attachMap.get("农村混杂结构房屋格网"), "农村混杂结构房屋格网", tempVersionCode, fxqhBuildingGridRuralMixedService);
        VersionParseFileVo vo11 = parseSaveGrid(attachMap.get("农村砌体结构房屋格网"), "农村砌体结构房屋格网", tempVersionCode, fxqhBuildingGridRuralMasonryService);
        VersionParseFileVo vo12 = parseSaveGrid(attachMap.get("农村土木石木结构房屋格网"), "农村土木石木结构房屋格网", tempVersionCode, fxqhBuildingGridRuralCivilService);
        VersionParseFileVo vo13 = parseSaveGrid(attachMap.get("农村底部框架结构房屋格网"), "农村底部框架结构房屋格网", tempVersionCode, fxqhBuildingGridRuralBottomFrameService);

        vo.setDataVersion(tempVersionCode);
        vo.setFieldNum(vo1.getFieldNum()
                + vo2.getFieldNum()
                + vo3.getFieldNum()
                + vo4.getFieldNum()
                + vo5.getFieldNum()
                + vo6.getFieldNum()
                + vo7.getFieldNum()
                + vo8.getFieldNum()
                + vo9.getFieldNum()
                + vo10.getFieldNum()
                + vo11.getFieldNum()
                + vo12.getFieldNum()
                + vo13.getFieldNum()
        );
        vo.setFieldEntry(vo1.getFieldEntry()
                + vo2.getFieldEntry()
                + vo3.getFieldEntry()
                + vo4.getFieldEntry()
                + vo5.getFieldEntry()
                + vo6.getFieldEntry()
                + vo7.getFieldEntry()
                + vo8.getFieldEntry()
                + vo9.getFieldEntry()
                + vo10.getFieldEntry()
                + vo11.getFieldEntry()
                + vo12.getFieldEntry()
                + vo13.getFieldEntry());
        return vo;
    }

    private VersionParseFileVo parseSaveGrid(List<AttachmentInfoEntity> attachmentInfoEntityList, String gridName, String tempVersionCode, ShpService service) throws Exception {
        Map<String, File> fileMap = this.uniformFileName(attachmentInfoEntityList);
        try {
            ParsingResult fxqhBuildingGridUrbanOtherShpData = getShpData(fileMap);
            if (!fxqhBuildingGridUrbanOtherShpData.getMessage().equals("ok")) {
                throw new RuntimeException(gridName + fxqhBuildingGridUrbanOtherShpData.getMessage());
            }
            return service.parseData(fxqhBuildingGridUrbanOtherShpData, tempVersionCode);
        } catch (BufferUnderflowException | IllegalArgumentException bue) {
            log.error(bue.getMessage(), bue);
            throw new ShpFieldException(gridName +"暂时不支持三维空间数据的导入，请上传二维空间数据，如果您的文件在其他程序打开是平面的展示，请检查是否为三维或者自己强行转为二维后再次尝试");
        } catch (ShpFieldException e) {
            throw new ShpFieldException(gridName + e.getMessage());
        } finally {
            for (File file : fileMap.values()) {
                FileUtil.del(file);
            }
        }
    }

    /**
     * 解析tif文件返回tif数据
     *
     * @param fileMap 文件ids以,分割
     * @return
     */
    public ParsingResult getTifData(Map<String, File> fileMap) throws Exception {
        // .tif文件用来获得数据
        String tif = fileMap.get(".shp") == null ? StringUtils.EMPTY : fileMap.get(".shp").getPath();
        return TifAnalyticUtil.analytic(tif);
    }

//    /**
//     * 解析tif并存储临时数据
//     *
//     * @param fileIds  tif文件id
//     * @param typeCode
//     * @return
//     */
//    public VersionParseFileVo parseTif(String fileIds, String typeCode) throws Exception {
//        Map<String, File> fileMap = this.uniformFileName(fileIds);
//        try {
//            ShpService shpService = strategyFactory.getShpService(typeCode);
//            // 解析shp
//            ParsingResult tifData = getTifData(fileMap);
//            // 是否成功
//            if (!tifData.getMessage().equals("ok")) {
//                throw new RuntimeException(tifData.getMessage());
//            }
//            return shpService.parseData(tifData);
//        } finally {
//            for (File file : fileMap.values()) {
//                FileUtil.del(file);
//            }
//        }
//    }

    /**
     * 统一文件名，提取出临时文件
     *
     * @param fileIds 文件ids，通过”,“拼接
     */
    public Map<String, File> uniformFileName(String fileIds) throws FileNotFoundException {
        String[] idList = fileIds.split(",");
        String tempFileName = System.currentTimeMillis() + "";
        Map<String, File> fileMap = new HashMap<>();
        for (String attachId : idList) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(attachId);
            File targetFile = new File(ResourceUtils.getURL("classpath:").getPath() + File.separator + "cache_file" + File.separator + tempFileName + "." + FileUtil.getSuffix(attach.getAttachName()));
            FileUtil.copy(new File(localDir + File.separator + attach.getAttachPath()), targetFile, true);
            fileMap.put("." + FileUtil.getSuffix(attach.getAttachName()), targetFile);
        }
        return fileMap;
    }

    /**
     * 统一文件名，提取出临时文件
     */
    public Map<String, File> uniformFileName(List<AttachmentInfoEntity> attachList) throws FileNotFoundException {
        String tempFileName = IdUtil.simpleUUID();
        Map<String, File> fileMap = new HashMap<>();
        for (AttachmentInfoEntity attach : attachList) {
            File targetFile = new File(ResourceUtils.getURL("classpath:").getPath() + File.separator + "cache_file" + File.separator + tempFileName + "." + FileUtil.getSuffix(attach.getAttachName()));
            FileUtil.copy(new File(localDir + File.separator + attach.getAttachPath()), targetFile, true);
            fileMap.put("." + FileUtil.getSuffix(attach.getAttachName()), targetFile);
        }
        return fileMap;
    }

    /**
     * 检查空间文件的完整性
     *
     * @param fileIds
     * @return
     */
    public boolean shpFileAllHasCheck(String fileIds) {
        String[] split = fileIds.split(",");
        Map<String, Boolean> map = new HashMap<>();
        map.put("shp", false);
        map.put("prj", false);
        map.put("dbf", false);
        map.put("cpg", false);
        map.put("shx", false);
        for (String id : split) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(id);
            if (attach == null) {
                throw new RuntimeException("文件不存在");
            }
            String suffix = FileUtil.getSuffix(attach.getAttachName());
            if (map.get(suffix) != null) {
                map.put(suffix, true);
            }
        }
        for (Boolean value : map.values()) {
            if (!value) {
                return false;
            }
        }
        return true;
    }

    /**
     * 检查tif文件的完整性
     *
     * @param fileIds
     * @return
     */
    public boolean tifFileAllHasCheck(String fileIds) {
        String[] split = fileIds.split(",");
        Map<String, Boolean> map = new HashMap<>();
        map.put("tif", false);
        for (String id : split) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(id);
            String suffix = FileUtil.getSuffix(attach.getAttachName());
            if (map.get(suffix) != null) {
                map.put(suffix, true);
            }
        }
        for (Boolean value : map.values()) {
            if (!value) {
                return false;
            }
        }
        return true;
    }

//    public Map<String, Object> dataVersionIsUseForDel(String versionCode) {
//        List<SysSubsystemUseRecord> sysUseRecords = sysUseRecordRepo.selectByVersionCode(versionCode);
//        return new HashMap<String, Object>() {
//            {
//                put("isUse", !sysUseRecords.isEmpty());
//                if (!sysUseRecords.isEmpty()) {
//                    for (SysSubsystemUseRecord sysUseRecord : sysUseRecords) {
//                        put(
//                                "useSysList",
//                                new HashMap<String, Object>() {
//                                    {
//                                        put(
//                                                "sysName",
//                                                sysSubsystemService.selectById(sysUseRecord.getSubsystemId()).getName());
//                                        put("operation", sysUseRecord.getOperation());
//                                    }
//                                });
//                    }
//                    put(
//                            "message",
//                            sysUseRecords.stream()
//                                    .map(o -> sysSubsystemService.selectById(o.getSubsystemId()).getName())
//                                    .collect(Collectors.joining("、"))
//                                    + "子系统使用了该版本数据产生了"
//                                    + sysUseRecords.stream()
//                                    .map(o -> SubsystemUseOpEnum.getByCode(o.getOperation()).getName())
//                                    .collect(Collectors.joining("、"))
//                                    + "结果，如删除"
//                                    + sysUseRecords.stream()
//                                    .map(o -> SubsystemUseOpEnum.getByCode(o.getOperation()).getName())
//                                    .collect(Collectors.joining("、"))
//                                    + "结果无效，确认是否继续？");
//                }
//            }
//        };
//    }

    /**
     * 导出数据视图
     *
     * @param response
     * @param param
     */
    public void exportDataView(HttpServletResponse response, FxqhBuildingGridDataVersionPageParam param)
            throws StrategyFactoryException, IOException, BizException {
        String dataType = param.getDataType();
//        if (dataType != null) {
        ShpService shpService = strategyFactory.getShpService(dataType);
        shpService.dataExport(response, param.getVersionCode());
//        } else {
//            FxqhBuildingGridDataVersion version = fxqhBuildingGridVersionRepository.selectByVersionCode(param.getVersionCode());
//            if (version.getDataType() == null) {
//                if (StringUtils.isBlank(dataType)) {
//                    throw new BizException("版本数据错误，未找到数据类别");
//                }
//            }
//            ShpService shpService = strategyFactory.getShpService(version.getDataType());
//            shpService.dataExport(response, param.getVersionCode());
//        }
    }

    /**
     * 多条件查询数据版本列表
     *
     * @param param 查询条件参数
     * @return
     */
    public List<FxqhBuildingGridDataVersionPageVo> list(FxqhBuildingGridDataVersionPageParam param) throws BizException {
        resetPageParam(param);
        param.setPage(param.getRows() * (Math.max(param.getPage(), 1) - 1));
        // 构建上传人用户名查询
        if (StringUtils.isNotBlank(param.getUploadUsername())) {
            param.setUploadUserIds(
                    StringUtils.join(
                            this.getLikeUsernameUploadUserId(param.getUploadUsername()),
                            "','"));
        }
        List<String> idList = fxqhBuildingGridVersionRepository.selectList(param);
        List<FxqhBuildingGridDataVersion> list = new ArrayList<>();
        for (String id : idList) {
            list.add(this.getById(id));
        }
        return this.entity2FxqhBuildingGridDataVersionPageVoForList(list);
    }

    /**
     * 重置分页参数
     *
     * @param sysDataVersionPageParam
     */
    private static void resetPageParam(FxqhBuildingGridDataVersionPageParam sysDataVersionPageParam) {
        sysDataVersionPageParam.setRows(null);
        sysDataVersionPageParam.setPage(null);
    }

    /**
     * @return
     */
    public QueryByVersionVo<?> queryDataVersionByParam(QueryByVersionParam queryByVersionParam) throws StrategyFactoryException, BizException {
//        if (StringUtils.isNotBlank(queryByVersionParam.getTypeCode())) {
        return strategyFactory.getShpService(queryByVersionParam.getTypeCode()).queryDataByVersionCode(queryByVersionParam);
//        } else {
//            FxqhBuildingGridDataVersion version = fxqhBuildingGridVersionRepository.selectByVersionCode(queryByVersionParam.getVersionCode());
//            if (version == null) {
//                throw new BizException("错误的版本号");
//            }
//            String dataType = version.getDataType();
//            if (StringUtils.isBlank(dataType)) {
//                throw new BizException("版本数据错误，未找到数据类别");
//            }
//            return strategyFactory.getShpService(dataType).queryDataByVersionCode(queryByVersionParam);
//        }
    }

    // 根据地震影响场查询对应的公里网格数据
    public List<Grid13VO> queryDataByParam(QueryByVersionParam queryByVersionParam) throws StrategyFactoryException {
        return strategyFactory.getShpService(queryByVersionParam.getTypeCode()).queryDataByParam(queryByVersionParam);
    }
    // 根据地震影响场查询对应的公里网格数据-经济损失
    public List<Grid13VO> queryDataByParam1(QueryByVersionParam queryByVersionParam) throws StrategyFactoryException {
        return strategyFactory.getShpService(queryByVersionParam.getTypeCode()).queryDataByParam1(queryByVersionParam);
    }

    /**
     * 根据id查询数据
     *
     * @param id
     * @param typeCode
     * @return
     */
    public BuildingGridGetByIdVo<?> queryBuildingGridById(String id, String typeCode) throws StrategyFactoryException {
        return strategyFactory.getShpService(typeCode).findById(id);
    }

    /**
     * 根据版本号查询版本数据
     *
     * @param versionCode
     * @return
     */
    public FxqhBuildingGridDataVersion getByVersionCode(String versionCode) {
        return fxqhBuildingGridVersionRepository.selectByVersionCode(versionCode);
    }

    /**
     * 从缓存取，取不到从数据库取
     *
     * @param id
     * @return
     */
    public FxqhBuildingGridDataVersion getById(String id) {
        ValueOperations<String, FxqhBuildingGridDataVersion> valueOperations =
                redisTemplate.opsForValue();
        FxqhBuildingGridDataVersion version =
                valueOperations.get(FXQH_BUILDING_GRID_VERSION_DETAILS_CACHE + id);
        if (version == null) {
            version = fxqhBuildingGridVersionRepository.selectById(id);
            if (version == null) {
                return null;
            }
            valueOperations.set(FXQH_BUILDING_GRID_VERSION_DETAILS_CACHE + id, version);
            redisTemplate.expire(FXQH_BUILDING_GRID_VERSION_DETAILS_CACHE + id, 60, TimeUnit.MINUTES);
        }
        return version;
    }

//    public RestResponse<List<AttachmentInfoEntity>> queryTempUploadById(
//            String id, String typeCode, String field) {
//        String attachIds =
//                fxqhBuildingGridVersionRepository.selectJcFieldById(
//                        id, PgSQLTableDictEnum.getByCode(typeCode), field);
//        if (StringUtils.isNotBlank(attachIds)) {
//            List<AttachmentInfoEntity> resList = new ArrayList<>();
//            String[] idArr = attachIds.split(",");
//            for (String attId : idArr) {
//                resList.add(attachmentInfoService.getAttach(attId));
//            }
//            return RestResponse.succeed(resList);
//        }
//        return RestResponse.succeed();
//    }

//    public RestResponse<String> saveTempUploadById(
//            String typeCode, String id, String prop, String ids) {
//        PgSQLTableDictEnum table = getByCode(typeCode);
//        if (table == null) {
//            return RestResponse.fail("保存失败!");
//        }
//        if (table == JC_EARTHQUAKE_DAMAGE_SURVEY) {
//            if (prop.equals("isoline")) {
//                RestResponse<String> response = jcEarthquakeDamageSurveyService.saveIsoline(ids, id);
//                if (response.getCode() == 200) {
//                    fxqhBuildingGridVersionRepository.updateJcById(table, id, prop, ids);
//                }
//                return response;
//            }
//        }
//        fxqhBuildingGridVersionRepository.updateJcById(table, id, prop, ids);
//        return RestResponse.succeed();
//    }

    /**
     * 根据版本下载数据文件
     *
     * @param dataVersion
     * @param response
     */
    public void getDataFileByVersion(String dataVersion, HttpServletResponse response)
            throws IOException {
        FxqhBuildingGridDataVersion fxqhBuildingGridDataVersion =
                fxqhBuildingGridVersionRepository.selectByVersionCode(dataVersion);
        if (fxqhBuildingGridDataVersion == null) {
            return;
        }
        String dataFileIds = fxqhBuildingGridDataVersion.getDataFileIds();
        if (StringUtils.isBlank(dataFileIds)) {
            return;
        }
        List<File> fileList = new ArrayList<>();
        for (String attachId : dataFileIds.split(",")) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(attachId);
            if (attach == null) {
                continue;
            }
            fileList.add(FileUtil.file(localDir + File.separator + attach.getAttachPath()));
        }
        File zipFile = FileUtil.file("./temp_" + IdUtil.getSnowflakeNextIdStr() + ".zip");
        ZipUtil.zip(zipFile, false, fileList.toArray(new File[0]));
        response.reset();
        response.setContentType("application/octet-stream");
        response.setHeader(
                "Content-Disposition",
                "attachment;filename=\"" + URLEncoder.encode(dataVersion + ".zip", "UTF-8") + "\"");
        // 跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Method", "POST,GET");
        try (InputStream is = new FileInputStream(zipFile);
             OutputStream os = response.getOutputStream()) {
            int flag = 0;
            while ((flag = is.read()) != -1) {
                os.write(flag);
            }
        }
        zipFile.delete();
    }

    /**
     * 获取用户信息
     * <p>
     * 用户id
     * 先走缓存，缓存没有调接口，然后存储缓存，配置缓存60分钟过期
     */
    public SUser getUser(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        String redisKey = SYS_USER_INFO_KEY;
        ValueOperations<String, SUser> valueOperations = redisTemplate.opsForValue();
        SUser sUser = valueOperations.get(redisKey + userId);
        if (sUser != null) {
            return sUser;
        }
        String userJson = sUserService.getSUser(userId);
        if (StringUtils.isBlank(userJson)) {
            return null;
        }
        sUser = CreateGson.createGson().fromJson(userJson, SUser.class);
        valueOperations.set(redisKey + userId, sUser);
        redisTemplate.expire(redisKey + userId, 60, TimeUnit.MINUTES);
        return sUser;
    }

    public String getUsername(String userId) {
        SUser user = this.getUser(userId);
        if (user == null) {
            return null;
        }
        return user.getUserName();
    }

    public List<SUser> getUserCacheList() {
        Set<String> keys = redisTemplate.keys(SYS_USER_INFO_KEY + "*");
        ValueOperations<String, SUser> valueOperations = redisTemplate.opsForValue();
        return valueOperations.multiGet(keys);
    }

    /**
     * 根据区域名称查询区域id
     *
     * @param areaId
     * @return
     */
    public String getAreaNameByAreaIdFromCache(String areaId) {
        if (StringUtils.isBlank(areaId)) {
            return null;
        }
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String value = ops.get(FxfzConstants.CACHE_SYS_KEY + "areaMap");
        if (StringUtils.isNotBlank(value)) {
            JSONObject jsonObject = JSONObject.parseObject(value);
            String areaName = (String) jsonObject.get(areaId);
            if (StringUtils.isNotBlank(areaName)) {
                return areaName;
            } else {
                return sysAreaService.getAreaNameByAreaId(areaId);
            }
        } else {
            return sysAreaService.getAreaNameByAreaId(areaId);
        }
    }

    /**
     * 查询字段说明
     *
     * @return
     */
    public List<ListFileDescByDataTypeVo> listFileDescByDataType() {
        List<ListFileDescByDataTypeVo> voList = new ArrayList<>();
        ListFileDescByDataTypeVo vo1 = new ListFileDescByDataTypeVo();
        vo1.setName("城镇砌体结构房屋格网");
        vo1.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("czqtjggw"));

        ListFileDescByDataTypeVo vo2 = new ListFileDescByDataTypeVo();
        vo2.setName("城镇钢混结构房屋格网");
        vo2.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("czghjggw"));

        ListFileDescByDataTypeVo vo3 = new ListFileDescByDataTypeVo();
        vo3.setName("城镇钢结构房屋格网");
        vo3.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("czgjggw"));

        ListFileDescByDataTypeVo vo4 = new ListFileDescByDataTypeVo();
        vo4.setName("城镇木结构房屋格网");
        vo4.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("czmjggw"));

        ListFileDescByDataTypeVo vo5 = new ListFileDescByDataTypeVo();
        vo5.setName("城镇其他结构房屋格网");
        vo5.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("czqtjglxgw"));

        ListFileDescByDataTypeVo vo6 = new ListFileDescByDataTypeVo();
        vo6.setName("农村砌体结构房屋格网");
        vo6.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("ncqtjggw"));

        ListFileDescByDataTypeVo vo7 = new ListFileDescByDataTypeVo();
        vo7.setName("农村土木（石木）结构房屋格网");
        vo7.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("nctmsmjggw"));

        ListFileDescByDataTypeVo vo8 = new ListFileDescByDataTypeVo();
        vo8.setName("农村底部框架结构房屋格网");
        vo8.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("ncdbkjkzqqtjggw"));

        ListFileDescByDataTypeVo vo9 = new ListFileDescByDataTypeVo();
        vo9.setName("农村木（竹）结构房屋格网");
        vo9.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("ncmzjggw"));

        ListFileDescByDataTypeVo vo10 = new ListFileDescByDataTypeVo();
        vo10.setName("农村混杂结构房屋格网");
        vo10.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("nchzjggw"));

        ListFileDescByDataTypeVo vo11 = new ListFileDescByDataTypeVo();
        vo11.setName("农村钢混结构房屋格网");
        vo11.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("ncghjggw"));

        ListFileDescByDataTypeVo vo12 = new ListFileDescByDataTypeVo();
        vo12.setName("农村钢结构房屋格网");
        vo12.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("ncgjggw"));

        ListFileDescByDataTypeVo vo13 = new ListFileDescByDataTypeVo();
        vo13.setName("农村其他结构房屋格网");
        vo13.setList(fxqhBuildingGridFieldDescRepository.listByBuildGridType("ncqtjglxgw"));

        voList.add(vo1);
        voList.add(vo2);
        voList.add(vo3);
        voList.add(vo4);
        voList.add(vo5);
        voList.add(vo6);
        voList.add(vo7);
        voList.add(vo8);
        voList.add(vo9);
        voList.add(vo10);
        voList.add(vo11);
        voList.add(vo12);
        voList.add(vo13);
        return voList;
    }

    /**
     * 检查数据类型是否存在
     *
     * @param dataType
     * @return
     */
    public boolean checkDataTypeExists(String dataType) {
        if (dataType == null) {
            return false;
        }
        List<DictEntityVo> dictVoList = dictItemService.getDictItemByDictCode(DICT_CODE);
        if (dictVoList == null) {
            return false;
        }
        for (DictEntityVo dictEntityVo : dictVoList) {
            if (dictEntityVo.getDictItemCode().equals(dataType)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 现场灾害list
     *
     * @return
     */
    public PageResult<FxqhBuildingGridDataVersion> xczhList(int current, int size) {
        FxqhBuildingGridDataVersionPageParam query = new FxqhBuildingGridDataVersionPageParam();
        query.setPage(current);
        query.setRows(size);
        List<String> idList = fxqhBuildingGridVersionRepository.selectList(query);
        Integer total = fxqhBuildingGridVersionRepository.selectCount(query);
        List<FxqhBuildingGridDataVersion> list = new ArrayList<>();
        for (String id : idList) {
            list.add(this.getById(id));
        }
        return PageResult.build(current, size, total, list);
    }

    public List<?> listGridDataByVersionCode(String version, String type) throws StrategyFactoryException {
        return strategyFactory.getShpService(type).listGridDataByVersionCode(version);
    }

    public List<Grid13VO> queryYwData(QueryByVersionParam queryByVersionParam) throws StrategyFactoryException {
        return strategyFactory.getShpService(queryByVersionParam.getTypeCode()).queryYwData(queryByVersionParam);
    }

    public List<Grid13VO> getJcld(QueryByVersionParam queryByVersionParam)throws StrategyFactoryException {
        return strategyFactory.getShpService(queryByVersionParam.getTypeCode()).getJcld(queryByVersionParam);
    }

    public List<Grid13VO> getPga(QueryByVersionParam queryByVersionParam)throws StrategyFactoryException {
        return strategyFactory.getShpService(queryByVersionParam.getTypeCode()).getPga(queryByVersionParam);
    }

    public void exportShp(String name, String versionId, HttpServletResponse response){
        String ids = fxqhBuildingGridFieldDescRepository.getDataFileDisById(versionId);
        ArrayList<AttachmentInfoEntity> attachList = new ArrayList<>();
        List<String> fileNameList = new ArrayList<>();
        for (String id : ids.split(",")) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(id);
            if(attach.getAttachName().contains(name.split("_")[0])){
                attachList.add(attach);
                fileNameList.add(attach.getAttachName());
            }
        }
        File[] srcFiles =new File[attachList.size()] ;
        for (int i=0;i<attachList.size();i++){
            srcFiles[i]=new File(localDir+attachList.get(i).getAttachPath());
        }
        ExportZipUtils.createZipFile(response,srcFiles,fileNameList,name);
    }

    public void delDataById(String ids, String typeCode) throws StrategyFactoryException {
        for (String id : ids.split(",")) {
            strategyFactory.getShpService(typeCode).delDataById(id);
        }
    }


    @Data
    public static class SysDataVersionExportModel {
        private String versionTime;
        private String versionCode;
        private String dataName;
        private String dataType;
        private String dataRange;
        private String uploadTime;
        private String uploadUser;
        private String versionDesc;
        private String dataDesc;
        private String updateDesc;
    }
}
